// @author: caoshi
// @date: 2021-04-25 21:46

// 读写锁
// 1. 可以随便读, 多个goroutine同时读
// 2. 写操作的时候, 其它读写操作均无法进行

package main

import (
	"fmt"
	"sync"
	"time"
)

// 读写锁对象
var rwMutex *sync.RWMutex

// 同步等待组指针
var wgp *sync.WaitGroup

func main() {
	rwMutex = new(sync.RWMutex)
	wgp = new(sync.WaitGroup)

	// 只进行读操作, 读是可以同时进行的
	//wgp.Add(2)
	//go readData(1)
	//go readData(2)

	// 读写混合起来操作
	wgp.Add(3)
	go writeData(1)
	go readData(2)
	go writeData(3)

	wgp.Wait()
	fmt.Println("main 函数执行完毕 ")

}

// 写数据函数
func writeData(i int) {
	defer wgp.Done()
	fmt.Println(i, "开始写 write start..")
	rwMutex.Lock()
	fmt.Println(i, "正在写 writing... ")
	time.Sleep(3 * time.Second)
	rwMutex.Unlock()
	fmt.Println(i, "写结束 write over")
}

// 读数据函数
// 读操作可以同时进行
func readData(i int) {
	defer wgp.Done() // 每个goroutine结束必须执行 Done
	fmt.Println(i, "开始读 read start..")
	rwMutex.RLock()
	fmt.Println(i, "正在读数据: read start..")
	time.Sleep(3 * time.Second)
	rwMutex.RUnlock()
	fmt.Println(i, "读结束: read over..")
}
